﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace Jinndev {

    public static class UIUtil {


        public static void ForceLayout(Transform transform) {
            if (transform != null) {
                LayoutGroup[] groups = transform.GetComponentsInParent<LayoutGroup>();
                if (groups.Length > 0) {
                    LayoutGroup group = groups[groups.Length - 1];
                    LayoutRebuilder.ForceRebuildLayoutImmediate(group.transform as RectTransform);
                }
                else {
                    LayoutRebuilder.ForceRebuildLayoutImmediate(transform as RectTransform);
                }
            }
        }

        public static void ForceLayout(Object parent, string path) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            ForceLayout(transform);
        }

        public static void SetSizeDeltaX(this RectTransform transform, float width) {
            if (transform != null) {
                Vector2 sizeDelta = transform.sizeDelta;
                sizeDelta.x = width;
                transform.sizeDelta = sizeDelta;
            }
        }

        public static void SetSizeDeltaX(Object parent, string path, float width) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            SetSizeDeltaX(transform, width);
        }

        public static void SetSizeDeltaY(this RectTransform transform, float height) {
            if (transform != null) {
                Vector2 sizeDelta = transform.sizeDelta;
                sizeDelta.y = height;
                transform.sizeDelta = sizeDelta;
            }
        }

        public static void SetSizeDeltaY(Object parent, string path, float height) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            SetSizeDeltaY(transform, height);
        }

        public static void SetOffset(Object parent, string path, Vector2 offsetMin, Vector2 offsetMax) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                transform.offsetMin = offsetMin;
                transform.offsetMax = offsetMax;
            }
        }

        public static void SetAnchor(Object parent, string path, Vector2 anchorMin, Vector2 anchorMax) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                transform.anchorMin = anchorMin;
                transform.anchorMax = anchorMax;
            }
        }

        public static void SetPivot(Object parent, string path, Vector2 pivot) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                transform.pivot = pivot;
            }
        }

        public static void SetAnchoredPos(Object parent, string path, Vector2 anchoredPosition) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                transform.anchoredPosition = anchoredPosition;
            }
        }

        public static void SetAnchoredPosX(Object parent, string path, float x) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                Vector2 anchoredPosition = transform.anchoredPosition;
                anchoredPosition.x = x;
                transform.anchoredPosition = anchoredPosition;
            }
        }

        public static void SetAnchoredPosY(Object parent, string path, float y) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                Vector2 anchoredPosition = transform.anchoredPosition;
                anchoredPosition.y = y;
                transform.anchoredPosition = anchoredPosition;
            }
        }

        public static void SetAnchorPosX(this RectTransform transform, float x) {
            Vector2 pos = transform.anchoredPosition;
            pos.x = x;
            transform.anchoredPosition = pos;
        }

        public static void SetAnchorPosY(this RectTransform transform, float y) {
            Vector2 pos = transform.anchoredPosition;
            pos.y = y;
            transform.anchoredPosition = pos;
        }

        public static void SetImage(Object parent, string path, Sprite sprite) {
            Image com = CommonUtil.GetComponent<Image>(parent, path);
            if (com != null) {
                com.sprite = sprite;
            }
        }

        public static void SetRawImage(Object parent, string path, Texture2D texture) {
            RawImage com = CommonUtil.GetComponent<RawImage>(parent, path);
            if (com != null) {
                com.texture = texture;
            }
        }

        public static void SetImageColor(Object parent, string path, Color color) {
            Image com = CommonUtil.GetComponent<Image>(parent, path);
            if (com != null) {
                com.color = color;
            }
        }

        public static void SetRawImageColor(Object parent, string path, Color color) {
            RawImage com = CommonUtil.GetComponent<RawImage>(parent, path);
            if (com != null) {
                com.color = color;
            }
        }

        public static void SetText(Object parent, string path, string text) {
            Text com = CommonUtil.GetComponent<Text>(parent, path);
            if (com != null) {
                com.text = text;
            }
        }

        public static void SetTextColor(Object parent, string path, Color color) {
            Text com = CommonUtil.GetComponent<Text>(parent, path);
            if (com != null) {
                com.color = color;
            }
        }

        public static void SetTextAndColor(Object parent, string path, string text, Color color) {
            Text com = CommonUtil.GetComponent<Text>(parent, path);
            if (com != null) {
                com.text = text;
                com.color = color;
            }
        }

        public static string GetText(Object parent, string path) {
            Text com = CommonUtil.GetComponent<Text>(parent, path);
            if (com != null) {
                return com.text;
            }
            return null;
        }

        public static void SetInputText(Object parent, string path, object text) {
            InputField com = CommonUtil.GetComponent<InputField>(parent, path);
            if (com != null) {
                com.text = text == null ? null : text.ToString();
            }
        }

        public static string GetInputText(Object parent, string path, string defaultValue = null) {
            InputField com = CommonUtil.GetComponent<InputField>(parent, path);
            if (com != null) {
                return string.IsNullOrEmpty(com.text) ? defaultValue : com.text;
            }
            return defaultValue;
        }

        public static void AddInputChange(Object parent, string path, UnityAction<string> action) {
            InputField com = CommonUtil.GetComponent<InputField>(parent, path);
            if (com != null) {
                com.onValueChanged.RemoveAllListeners();
                com.onValueChanged.AddListener(action);
            }
        }

        public static void SetDropdownOptions(Object parent, string path, List<Dropdown.OptionData> options) {
            Dropdown com = CommonUtil.GetComponent<Dropdown>(parent, path);
            if (com != null) {
                com.options = options;
            }
        }

        public static void SetDropdownValue(Object parent, string path, int value) {
            Dropdown com = CommonUtil.GetComponent<Dropdown>(parent, path);
            if (com != null) {
                com.value = value;
            }
        }

        public static int GetDropdownValue(Object parent, string path) {
            Dropdown com = CommonUtil.GetComponent<Dropdown>(parent, path);
            if (com != null) {
                return com.value;
            }
            return -1;
        }

        public static void AddButtonClick(Object parent, string path, UnityAction action, bool removeBeforeAdd = true) {
            Button com = CommonUtil.GetComponent<Button>(parent, path);
            if (com != null) {
                if (removeBeforeAdd) {
                    com.onClick.RemoveAllListeners();
                }
                if (action != null) {
                    com.onClick.AddListener(action);
                }
            }
        }

        public static void AddMouseClick(Object parent, string path, PointerEventData.InputButton button, UnityAction<Vector2> action, bool removeBeforeAdd = true) {
            MouseClick com = CommonUtil.GetComponent<MouseClick>(parent, path);
            if (com != null) {
                if (button == PointerEventData.InputButton.Left) {
                    if (removeBeforeAdd) {
                        com.onLeftClick.RemoveAllListeners();
                    }
                    com.onLeftClick.AddListener(action);
                }
                else if (button == PointerEventData.InputButton.Right) {
                    if (removeBeforeAdd) {
                        com.onRightClick.RemoveAllListeners();
                    }
                    com.onRightClick.AddListener(action);
                }
                else if (button == PointerEventData.InputButton.Middle) {
                    if (removeBeforeAdd) {
                        com.onMiddleClick.RemoveAllListeners();
                    }
                    com.onMiddleClick.AddListener(action);
                }
            }
        }

        public static void AddToggleChange(Object parent, string path, UnityAction<bool> action, bool removeBeforeAdd = true) {
            Toggle com = CommonUtil.GetComponent<Toggle>(parent, path);
            if (com != null) {
                if (removeBeforeAdd) {
                    com.onValueChanged.RemoveAllListeners();
                }
                com.onValueChanged.AddListener(action);
            }
        }

        public static void SetToggleValue(Object parent, string path, bool isOn) {
            Toggle com = CommonUtil.GetComponent<Toggle>(parent, path);
            if (com != null) {
                com.isOn = isOn;
            }
        }

        public static bool GetToggleValue(Object parent, string path) {
            Toggle com = CommonUtil.GetComponent<Toggle>(parent, path);
            if (com != null) {
                return com.isOn;
            }
            return false;
        }

        public static ToggleGroup SetToggleGroup(Object parent, string path, Object groupParent, string groupPath) {
            Toggle com = CommonUtil.GetComponent<Toggle>(parent, path);
            if (com != null) {
                ToggleGroup group = CommonUtil.GetComponent<ToggleGroup>(groupParent, groupPath);
                if (group != null) {
                    com.group = group;
                    return group;
                }
            }
            return null;
        }

        public static void SetButtonInteractable(Object parent, string path, bool interactable) {
            Button com = CommonUtil.GetComponent<Button>(parent, path);
            if (com != null) {
                com.interactable = interactable;
            }
        }

        public static bool RawImageFitParent(RawImage rawImage, RectOffset padding = null) {
            if (rawImage == null || rawImage.texture == null) {
                return false;
            }
            RectTransform transform = rawImage.transform as RectTransform;
            RectTransform parent = transform.parent as RectTransform;

            Vector2 parentSize = parent.rect.size;
            if (padding != null) {
                parentSize -= new Vector2(padding.horizontal, padding.vertical);
            }
            Vector2 imageSize = new Vector2(rawImage.texture.width, rawImage.texture.height);

            imageSize *= parentSize.x / imageSize.x;
            if (imageSize.y > parentSize.y) {
                imageSize *= parentSize.y / imageSize.y;
            }
            transform.sizeDelta = imageSize;
            //Debug.Log(rawImage.texture.width + "," + rawImage.texture.height);
            //Debug.Log(parentSize);
            //Debug.Log(imageSize);

            if (padding != null) {
                transform.anchoredPosition = new Vector2(padding.left - padding.right, padding.bottom - padding.top) * 0.5f;
            }
            return true;
        }

    }
}
